// ActionScript file
import com.mit.web.business.proxy.SecurityProxy;
import com.mit.web.business.remote.IInvokeResponder;
import com.mit.web.config.Constants;
import com.mit.web.config.DisplayConfiguration;
import com.mit.web.config.SizeGroupConfig;
import com.mit.web.util.CachePool;
import com.mit.web.util.FlexSession;
import com.mit.web.util.LocaleUtil;
import com.mit.web.util.LogUtil;
import com.mit.web.util.MessageUtil;
import com.mit.web.view.maintenance.OrganizationWindow;
import com.mit.web.view.maintenance.PreferenceWindow;
import com.mit.web.vo.design.FabricVO;
import com.mit.web.vo.design.StyleVO;
import com.mit.web.vo.design.TemplatePartVO;
import com.mit.web.vo.design.TemplateVO;
import com.mit.web.vo.inventory.MaterialReceivedNoteItemVO;
import com.mit.web.vo.inventory.MaterialReceivedNoteVO;
import com.mit.web.vo.inventory.WarehouseVO;
import com.mit.web.vo.maintenance.EmployeeVO;
import com.mit.web.vo.maintenance.FabricCatVO;
import com.mit.web.vo.maintenance.OrganizationVO;
import com.mit.web.vo.maintenance.PaymentVO;
import com.mit.web.vo.maintenance.ProductColorVO;
import com.mit.web.vo.maintenance.ProductTypeVO;
import com.mit.web.vo.maintenance.SeasonVO;
import com.mit.web.vo.maintenance.UnitVO;
import com.mit.web.vo.manufacture.FactoryVO;
import com.mit.web.vo.manufacture.MOItemVO;
import com.mit.web.vo.manufacture.MOVO;
import com.mit.web.vo.purchase.ColorStyleVO;
import com.mit.web.vo.purchase.InquiryItemVO;
import com.mit.web.vo.purchase.InquiryTaskVO;
import com.mit.web.vo.purchase.MaterialVO;
import com.mit.web.vo.purchase.POItemVO;
import com.mit.web.vo.purchase.POVO;
import com.mit.web.vo.purchase.SupplierVO;
import com.mit.web.vo.sale.CustomerVO;
import com.mit.web.vo.sys.UserVO;

import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.net.SharedObject;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.registerClassAlias;

import flexlib.controls.tabBarClasses.SuperTab;
import flexlib.events.SuperTabEvent;

import mx.containers.TabNavigator;
import mx.containers.VBox;
import mx.controls.Alert;
import mx.events.FlexEvent;
import mx.events.MenuEvent;
import mx.logging.ILogger;
import mx.managers.PopUpManager;
import mx.modules.ModuleLoader;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;



[Bindable]
[Embed(source="../assets/document.png")]
private var document_icon:Class;

[Bindable]
[Embed(source="../assets/home.png")]
private var home_icon:Class;

public var moduleConfig:XML;
private var logger:ILogger;

private var securityProxy:SecurityProxy = SecurityProxy.getInstance();

private function init():void{

	//Load constants
	//Very important! Must be arranged in the first priority
	loadConstants();

	//Init Logger
	LogUtil.initLogger();
	
	logger = LogUtil.getLogger(this);
	logger.debug("Logger initialization complete!");
	
	var uo:SharedObject = SharedObject.getLocal(Constants.SO_USER_OPTION);

	txt_username.text = uo.data.username;
	txt_username.setFocus();
	chk_rememberme.selected = uo.data.rememberme;	

}

private function pwdKeyDownHanlder(event:KeyboardEvent):void{
	if(event.keyCode == 13)
		doLogin();
}

/**
 * 登录按钮按下的事件
 * */
private function login(event:MouseEvent):void{
	doLogin();

}

private function doLogin():void{
	var username:String = txt_username.text;
	var password:String = txt_pwd.text;
	var responder:IInvokeResponder = securityProxy.getUserAccount(username, password);
	responder.addResultListener(validateUserAccount);
	responder.addFaultListener(handleRemoteFault);
}

private function validateUserAccount(e:ResultEvent):void{
	var user:UserVO = e.result as UserVO;
	if(user == null){
		//用户不存在
		logger.error("user name or password is wrong!");
		//提示
		//记录用户名
		//如果错误3次，锁定账户
		
	}else{
		//如果用户inactive
		if(!user.active){
			//提示账户已禁用
			logger.error("user is inactive!");
		}else{
			//更新用户的IP和登录时间
			//写入数据库日志
			//注册用户状态
			FlexSession.register(user);
			
			var userOption:SharedObject = SharedObject.getLocal(Constants.SO_USER_OPTION);
			if(chk_rememberme.selected){				
				userOption.data.username = user.username;
			}else{
				userOption.data.username = null;
			}
			userOption.data.rememberme = chk_rememberme.selected;
			userOption.flush();
			
			logger.info("login successfully!");
			//载入系统
			doDisplayMainApp();
		}
	}
}

private function handleRemoteFault(e:FaultEvent):void{
	logger.error("Can not reach remote service!");
	MessageUtil.popBackEndError(e, this);
}

private function doDisplayMainApp():void{

	
	this.currentState = "mainApp";	
	
	//Load event Handlers
	bar_menu.addEventListener(MenuEvent.ITEM_CLICK, clickMenu, false, 0, false);
	nav_main.addEventListener(SuperTabEvent.TAB_CLOSE, closeTab, false, 0, false);
	nav_main.addEventListener(FlexEvent.CREATION_COMPLETE, initNavigator);
}

private function initNavigator(e:FlexEvent){
	//set Home closable = false;
	nav_main.setClosePolicyForTab(0, SuperTab.CLOSE_NEVER);
	//加载模块，必须在切换state前
	loadModuleConfig();
}

private function loadConstants():void{
	registerAlias();
	//Load configuration
	com.mit.web.config.DisplayConfiguration.getInstance();
	com.mit.web.util.CachePool.getInstance();
	com.mit.web.util.LocaleUtil.getInstance();
	SizeGroupConfig.getInstance();
}

private function closeTab(e:SuperTabEvent):void{
	//********TODO should check is there any unsave operation at somewhere.
	var b:VBox = nav_main.getChildAt(e.tabIndex) as VBox;
	var m:ModuleLoader = b.getChildAt(0) as ModuleLoader;
	//*********TODO: What will happen if I dont unload module? Memory leak?
	m.unloadModule();
	// ********TODO: I don't know the effect on module loading and unloading!!!
}

private function loadModuleConfig():void{
	var xmlURL:URLRequest = new URLRequest(Constants.MODULE_CONFIG_FILE);
	var xmlLoader:URLLoader = new URLLoader(xmlURL);
	//dispatch load event
	xmlLoader.addEventListener(Event.COMPLETE, loadHomePage);
}

private function loadHomePage(e:Event):void{
	moduleConfig = XML(((e.currentTarget) as URLLoader).data);
	trace(Constants.MODULE_CONFIG_FILE + " loaded! ");
	//create home mudule
	var homeModule:ModuleLoader = createModule(Constants.MODULE_HOME_ID,
		moduleConfig.module.(@id == Constants.MODULE_HOME_ID).@url);
	box_home.addChild(homeModule);
}

private function getModuleIdByMenuId(menuId:String):String{
	return moduleConfig.module.(@menuid == menuId).@id;
}

private function getModuleURLByMenuId(menuId:String):String{
	return moduleConfig.module.(@menuid == menuId).@url;
}

private function createModule(id:String, url:String):ModuleLoader{
	var module:ModuleLoader = new ModuleLoader();
	module.id = id;
	module.autoLayout = true;
	module.url = url;
	module.percentHeight = 100;
	module.percentWidth = 100;
	return module;
}

private function clickMenu(e:MenuEvent):void{
	var menuId:String = e.item.@menuid;
	var tabName:String = e.item.@label;
	if(menuId== "c_00"){
		//弹出窗口
		var pwin:PreferenceWindow = new PreferenceWindow();	 
		PopUpManager.addPopUp(pwin,this,true);
		PopUpManager.centerPopUp(pwin);
	}else if(menuId == "c_01"){
		var owin:OrganizationWindow = new OrganizationWindow();	 
		PopUpManager.addPopUp(owin,this,true);
		PopUpManager.centerPopUp(owin);
	}else if(menuId == "c_04"){
		Alert.show("Version 0.0.1");
	}else{
	
		var t:TabNavigator  = nav_main as TabNavigator;
		
		var tab:VBox = t.getChildByName(tabName) as VBox;
		if(!tab){
			//If tab not exist, create a new tab
			addTab(tabName, menuId, nav_main);		
			tab = t.getChildAt(t.length - 1) as VBox;
		}
		//swith to the properate tab
		t.selectedChild = tab;
	}
}
/*
private function loadModule(mloader:ModuleLoader, murl:String):void{

	if(mloader.url == null)
		mloader.url = murl;
	else
		mloader.loadModule();
}
*/

private function addTab(lbl:String, menuId:String, navigator:SuperTabNavigator):void
{
	if (lbl == "")
		lbl = "(Untitled)";
	
	var curNum:Number = nav_main.numChildren + 1;
	
	var child:VBox = new VBox();	
	child.setStyle("closable", true);
	child.label = lbl;
	child.icon = document_icon;
	child.name = lbl;
	
	//create Module
	var module:ModuleLoader = createModule(getModuleIdByMenuId(menuId),
		getModuleURLByMenuId(menuId));

	child.addChild(module);	

	navigator.addChild(child);
}		

private function registerAlias():void{
	//package design
	registerClassAlias("com.mit.common.design.dto.FabricDTO", FabricVO);
	registerClassAlias("com.mit.common.design.dto.StyleDTO", StyleVO);
	registerClassAlias("com.mit.common.design.dto.TemplatePartDTO", TemplatePartVO);
	registerClassAlias("com.mit.common.design.dto.TemplateDTO", TemplateVO);
	
	//maintenance
	registerClassAlias("com.mit.common.maintenance.dto.EmployeeDTO", EmployeeVO);
	registerClassAlias("com.mit.common.maintenance.dto.FabricCatDTO", FabricCatVO);
	registerClassAlias("com.mit.common.maintenance.dto.PaymentDTO", PaymentVO);
	registerClassAlias("com.mit.common.maintenance.dto.ProductTypeDTO", ProductTypeVO);	
	registerClassAlias("com.mit.common.maintenance.dto.ProductColorDTO", ProductColorVO);
	registerClassAlias("com.mit.common.maintenance.dto.SeasonDTO", SeasonVO);
	registerClassAlias("com.mit.common.maintenance.dto.UnitDTO", UnitVO);
	registerClassAlias("com.mit.common.maintenance.dto.OrganizationDTO", OrganizationVO);
	
	//System
	registerClassAlias("com.mit.common.security.dto.UserDTO", UserVO);	
	
	//Purchase
	registerClassAlias("com.mit.common.purchase.dto.SupplierDTO", SupplierVO);
	registerClassAlias("com.mit.common.purchase.dto.MaterialDTO", MaterialVO);
	registerClassAlias("com.mit.common.purchase.dto.ColorStyleDTO", ColorStyleVO);
	registerClassAlias("com.mit.common.purchase.dto.InquiryTaskDTO", InquiryTaskVO);
	registerClassAlias("com.mit.common.purchase.dto.InquiryItemDTO", InquiryItemVO);
	registerClassAlias("com.mit.common.purchase.dto.PODTO", POVO);
	registerClassAlias("com.mit.common.purchase.dto.POItemDTO", POItemVO);
	
	//Manufacture
	registerClassAlias("com.mit.common.manufacture.dto.FactoryDTO", FactoryVO);
	registerClassAlias("com.mit.common.manufacture.dto.MODTO", MOVO);
	registerClassAlias("com.mit.common.manufacture.dto.MOItemDTO", MOItemVO);
	
	//Sale
	registerClassAlias("com.mit.common.sale.dto.CustomerDTO", CustomerVO);
	
	//Inventory
	registerClassAlias("com.mit.common.inventory.dto.WarehouseDTO", WarehouseVO);
	registerClassAlias("com.mit.common.inventory.dto.MaterialReceivedNoteDTO", MaterialReceivedNoteVO);
	registerClassAlias("com.mit.common.inventory.dto.MaterialReceivedNoteItemDTO", MaterialReceivedNoteItemVO);
}
